package tinybase.pf;

import java.util.LinkedList;

import tinybase.basic.IntegerWrapper;
import tinybase.basic.RC;

//--------------------------------------------------------------

//
// StatisticMgr class
//
// This class will track a dynamic list of statistics.
//
public class StatisticsMgr {

	private LinkedList<Statistic> llstat = null;
	
	public StatisticsMgr() {
		llstat = new LinkedList<Statistic>();
	}

	//
	// Register
	//
	// Register a change to a statistic.  The psKey is the char* name of
	// the statistic to be tracked.  This method will look for the statistic
	// name withing its list of statistics and perform the operation over the
	// stored value.  The piValue is utilized for some of the operations.
	//
	// Note: if the statistic isn't found (as it will not be the very first
	// time) then it will be initialized to 0 - the default value.
	//

	public RC register(String psKey, Stat_Operation op, IntegerWrapper piValue) {
		int i, iCount;
		Statistic stat= null;
		
		if (psKey == null || (op != Stat_Operation.STAT_ADDONE &&
				piValue == null))
			return RC.STAT_INVALID_ARGS;
		
		iCount= llstat.size();
		
		for (i= 0; i < iCount; i++) {
			stat= llstat.get(i);
			if (stat.psKey.equals(psKey))
				break;
		}
		
		// Check to see if we found the Stat
		if (i == iCount) 
			// We haven't found it so create a new statistic
		      // with the key psKey and initial value of 0.
			stat= new Statistic(psKey);

		// Now perform the operation over the statistic
		switch(op) {
		case STAT_ADDONE:
			stat.iValue++;
			break;
		case STAT_ADDVALUE:
			stat.iValue+= piValue.getValue();
			break;
		case STAT_SETVALUE:
			stat.iValue= piValue.getValue();
			break;
		case STAT_MULTVALUE:
			stat.iValue*= piValue.getValue();
			break;
		case STAT_DIVVALUE:
			stat.iValue= stat.iValue / piValue.getValue();
			break;
		case STAT_SUBVALUE:
			stat.iValue-= piValue.getValue();
			break;
		}
		
		// Finally, if the statistic wasn't in the original list then add it to
		   // the list.

		if (i == iCount) {
			llstat.add(stat);
		}
		return RC.SUCCESS;
	}

	
	//
	// Print
	//
	// Print out the information pertaining to a specific statistic

	public RC print(String psKey) {
		if (psKey == null)
			return RC.STAT_INVALID_ARGS;
		
		int iValue= get(psKey);
		
		if (iValue != -1)
			System.out.println(psKey+ "::" + iValue);
		else
			return RC.STAT_KNOWN_KEY;
		
		return RC.SUCCESS;
	}
	
	
	//
	// Get
	//
	// The Get method will return a pointer to the integer value associated
	// with a particular statistic.  If it cannot find the statistic then it
	// will return NULL.  The caller must remember to delete the memory
	// returned when done.
	//

	public int get(String psKey) {
		int i, iCount;
		Statistic stat= null;
		
		iCount= llstat.size();
		for(i= 0; i < iCount; i++) {
			stat= llstat.get(i);
			if (stat.psKey.equals(psKey))
				break;
		}
		
		 // Check to see if we found the Stat

		if (i == iCount)
			return -1;
		
		return stat.iValue;
	}
	
	//
	// Print
	//
	// Print out all the statistics tracked
	//
	public void print() {
		int i, iCount;
		Statistic stat= null;
		
		iCount= llstat.size();
		
		for(i= 0; i < iCount; i++) {
			stat= llstat.get(i);
			System.out.println(stat.psKey + "::" + stat.iValue);
		}
	}
	
	//
	// Reset
	//
	// Reset a specific statistic.  The easiest way to do this is to remove it
	// completely from the list
	//
	public RC reset(String psKey) {
		int i, iCount;
		Statistic stat= null;
		
		if (psKey == null) 
			return RC.STAT_INVALID_ARGS;
		
		iCount= llstat.size();
		
		for (i= 0; i < iCount; i++) {
			stat= llstat.get(i);
			if (stat.psKey.equals(psKey))
				break;
		}
		
		// If we found the statistic then remove it from the list
		if (i != iCount)
			llstat.remove(i);
		else
			return RC.STAT_KNOWN_KEY;
		
		return RC.SUCCESS;
	}
	
	
	//
	// Reset
	//
	// Reset all of the statistics.  The easiest way is to tell the linklist of
	// elements to Erase itself.
	//
	public void reset() {
		llstat.removeAll(llstat);
	}
	
	
	/**
	 * @param llstat the llstat to set
	 */
	public void setLlstat(LinkedList<Statistic> llstat) {
		this.llstat = llstat;
	}

	/**
	 * @return the llstat
	 */
	public LinkedList<Statistic> getLlstat() {
		return llstat;
	}
}
